package qdrant

import (
	"encoding/json"
	"fmt"
	"log"
	"os"
	"path/filepath"
	"sync"
	"time"
)

// SimpleQdrantClient 简化的Qdrant客户端实现
// 使用本地文件存储，为后续真实Qdrant集成做准备
type SimpleQdrantClient struct {
	config         *Config
	dataPath       string
	collectionName string
	vectors        map[string]*StoredVector
	mutex          sync.RWMutex
	initialized    bool
}

// StoredVector 存储的向量数据
type StoredVector struct {
	ID        string                 `json:"id"`
	Vector    []float32              `json:"vector"`
	Payload   map[string]interface{} `json:"payload"`
	Timestamp time.Time              `json:"timestamp"`
}

// NewSimpleQdrantClient 创建简化的Qdrant客户端
func NewSimpleQdrantClient() *SimpleQdrantClient {
	return &SimpleQdrantClient{
		vectors: make(map[string]*StoredVector),
	}
}

// Initialize 初始化客户端
func (sc *SimpleQdrantClient) Initialize(config *Config) error {
	sc.mutex.Lock()
	defer sc.mutex.Unlock()

	sc.config = config
	sc.dataPath = config.DataPath
	sc.collectionName = config.Collection.Name

	// 确保数据目录存在
	if err := os.MkdirAll(sc.dataPath, 0755); err != nil {
		return fmt.Errorf("failed to create data directory: %w", err)
	}

	// 加载现有数据
	if err := sc.loadVectors(); err != nil {
		log.Printf("Warning: failed to load existing vectors: %v", err)
	}

	sc.initialized = true
	log.Printf("SimpleQdrantClient initialized with data path: %s", sc.dataPath)
	return nil
}

// Close 关闭客户端
func (sc *SimpleQdrantClient) Close() error {
	sc.mutex.Lock()
	defer sc.mutex.Unlock()

	// 保存数据
	if err := sc.saveVectors(); err != nil {
		return fmt.Errorf("failed to save vectors: %w", err)
	}

	sc.initialized = false
	log.Println("SimpleQdrantClient closed")
	return nil
}

// HealthCheck 健康检查
func (sc *SimpleQdrantClient) HealthCheck() error {
	sc.mutex.RLock()
	defer sc.mutex.RUnlock()

	if !sc.initialized {
		return fmt.Errorf("client not initialized")
	}

	return nil
}

// InsertVectors 插入向量
func (sc *SimpleQdrantClient) InsertVectors(vectors []Vector) error {
	sc.mutex.Lock()
	defer sc.mutex.Unlock()

	if !sc.initialized {
		return fmt.Errorf("client not initialized")
	}

	for _, v := range vectors {
		sc.vectors[v.ID] = &StoredVector{
			ID:        v.ID,
			Vector:    v.Vector,
			Payload:   v.Payload,
			Timestamp: time.Now(),
		}
	}

	// 同步保存数据（避免并发问题）
	if err := sc.saveVectors(); err != nil {
		log.Printf("Failed to save vectors: %v", err)
	}

	log.Printf("Inserted %d vectors", len(vectors))
	return nil
}

// SearchVectors 搜索向量
func (sc *SimpleQdrantClient) SearchVectors(query Vector, limit int) ([]SearchResult, error) {
	sc.mutex.RLock()
	defer sc.mutex.RUnlock()

	if !sc.initialized {
		return nil, fmt.Errorf("client not initialized")
	}

	var results []SearchResult

	// 简化的相似度计算（余弦相似度）
	for _, stored := range sc.vectors {
		if len(stored.Vector) != len(query.Vector) {
			continue
		}

		similarity := sc.cosineSimilarity(query.Vector, stored.Vector)

		results = append(results, SearchResult{
			ID:      stored.ID,
			Score:   similarity,
			Payload: stored.Payload,
		})
	}

	// 按相似度排序
	sc.sortResultsByScore(results)

	// 限制结果数量
	if limit > 0 && len(results) > limit {
		results = results[:limit]
	}

	log.Printf("Search returned %d results", len(results))
	return results, nil
}

// DeleteVectors 删除向量
func (sc *SimpleQdrantClient) DeleteVectors(ids []string) error {
	sc.mutex.Lock()
	defer sc.mutex.Unlock()

	if !sc.initialized {
		return fmt.Errorf("client not initialized")
	}

	deleted := 0
	for _, id := range ids {
		if _, exists := sc.vectors[id]; exists {
			delete(sc.vectors, id)
			deleted++
		}
	}

	// 异步保存数据
	go func() {
		if err := sc.saveVectors(); err != nil {
			log.Printf("Failed to save vectors: %v", err)
		}
	}()

	log.Printf("Deleted %d vectors", deleted)
	return nil
}

// CreateCollection 创建集合（简化实现）
func (sc *SimpleQdrantClient) CreateCollection(name string, config CollectionConfig) error {
	log.Printf("Collection %s created (simplified implementation)", name)
	return nil
}

// DeleteCollection 删除集合（简化实现）
func (sc *SimpleQdrantClient) DeleteCollection(name string) error {
	sc.mutex.Lock()
	defer sc.mutex.Unlock()

	sc.vectors = make(map[string]*StoredVector)

	if err := sc.saveVectors(); err != nil {
		return fmt.Errorf("failed to save after collection deletion: %w", err)
	}

	log.Printf("Collection %s deleted", name)
	return nil
}

// GetCollectionInfo 获取集合信息
func (sc *SimpleQdrantClient) GetCollectionInfo(name string) (*CollectionInfo, error) {
	sc.mutex.RLock()
	defer sc.mutex.RUnlock()

	if !sc.initialized {
		return nil, fmt.Errorf("client not initialized")
	}

	return &CollectionInfo{
		Name:        name,
		VectorCount: int64(len(sc.vectors)),
		Status:      "green",
	}, nil
}

// 辅助方法

// loadVectors 从文件加载向量数据
func (sc *SimpleQdrantClient) loadVectors() error {
	filePath := filepath.Join(sc.dataPath, "vectors.json")

	if _, err := os.Stat(filePath); os.IsNotExist(err) {
		return nil // 文件不存在，跳过加载
	}

	data, err := os.ReadFile(filePath)
	if err != nil {
		return err
	}

	return json.Unmarshal(data, &sc.vectors)
}

// saveVectors 保存向量数据到文件
func (sc *SimpleQdrantClient) saveVectors() error {
	filePath := filepath.Join(sc.dataPath, "vectors.json")

	data, err := json.MarshalIndent(sc.vectors, "", "  ")
	if err != nil {
		return err
	}

	return os.WriteFile(filePath, data, 0644)
}

// cosineSimilarity 计算余弦相似度
func (sc *SimpleQdrantClient) cosineSimilarity(a, b []float32) float32 {
	if len(a) != len(b) {
		return 0
	}

	var dotProduct, normA, normB float32

	for i := 0; i < len(a); i++ {
		dotProduct += a[i] * b[i]
		normA += a[i] * a[i]
		normB += b[i] * b[i]
	}

	if normA == 0 || normB == 0 {
		return 0
	}

	return dotProduct / (float32(sqrt(float64(normA))) * float32(sqrt(float64(normB))))
}

// sqrt 简单的平方根实现
func sqrt(x float64) float64 {
	if x == 0 {
		return 0
	}

	z := x
	for i := 0; i < 10; i++ {
		z = (z + x/z) / 2
	}
	return z
}

// sortResultsByScore 按分数排序结果
func (sc *SimpleQdrantClient) sortResultsByScore(results []SearchResult) {
	for i := 0; i < len(results)-1; i++ {
		for j := i + 1; j < len(results); j++ {
			if results[i].Score < results[j].Score {
				results[i], results[j] = results[j], results[i]
			}
		}
	}
}
